import type { INode } from "../graph/node/instance";
import type { Graph } from "../graph/graph";

/**
 * TGAstNode - 用于代码编译的工具类。
 * 
 * 实际上负责的是将图中的节点转化成语法树。
 * 并不负责每一条语句的解释，这是语句节点本身(PNode)负责的
 */
export class AstNode {

  public children: AstNode[] = []

  /**
   * 
   * @param node 对应的Graph节点
   * @param depth 节点的分支深度
   * @param graph 节点所属的Graph
   */
  constructor(
    public node: INode,
    public depth: number,
    public graph: Graph,
  ) { }


  // 生成一个branch
  static _parse(node: INode, depth: number, root: Graph): AstNode {

    const ast = new AstNode(node, depth, root)

    // 所有可能的下一个graph节点
    const allNextSlot = node.getProcessSlots()
      .filter(s => s.prototype.direction === 'out')
      .filter(s => s.inUse)

    // 都添加到子ast节点
    ast.children = allNextSlot.map(slot => {
      // 如果是非主要分支，那深度+1
      const _depth = slot.prototype.name === '_out' ? depth : (depth + 1)
      const peerNode = root.nodes.find(node => node.slots.indexOf(slot.peer!) >= 0)!
      // console.log(`当前: ${node.prototype.name}\n- 添加了:${peerNode.prototype.name}, 深度: ${_depth}`);
      
      return this._parse(peerNode, _depth, root)
    })

    return ast
  }


  static parse(graph: Graph): AstNode {
    // 获取开始节点
    const startNode = graph.getStartNode()
    if (!startNode) {
      throw new Error('this.getStartNode() return nothing')
    }

    const firstNode = startNode.getNextNode(graph)
    if (!firstNode) {
      throw new Error('开始节点似乎没有连接')
    }

    const astRoot = this._parse(firstNode, 0, graph)
    
    return astRoot
  }
}
